package com.fjh.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjh.constant.MenuConstant;
import com.fjh.domain.SysMenu;
import com.fjh.mapper.SysMenuMapper;
import com.fjh.mapper.SysUserMapper;
import com.fjh.service.SysMenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService{

    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    /**
     * 查询当前用户的树菜单 每个用户的菜单数据比较多 我们建议使用缓存  其实外面开发中 只要是查询 都要使用缓存
     * 1.查缓存  （使用代码的方式缓存）
     * 2.缓存没有查询数据库
     * 3.缓存有直接拿到
     * 4.组装树菜单
     * @param userId
     * @return
     */
    @Override
    public List<SysMenu> loadTreeByUserId(String userId) {
        log.info("查询用户{},的菜单",userId);
        String menuStr = redisTemplate.opsForValue().get(MenuConstant.MENU_PREFIX + userId);
        List<SysMenu> sysMenus = null;
        if (StringUtils.hasText(menuStr)) {
            // redis有值  字符串转成集合
            sysMenus = JSON.parseArray(menuStr, SysMenu.class);
        } else {
            sysMenus = sysMenuMapper.findUserMenu(userId);
            if (!CollectionUtils.isEmpty(sysMenus)) {
                // 存入redis  存的东西最好设定一个过期时间
                redisTemplate.opsForValue().set(MenuConstant.MENU_PREFIX + userId, JSON.toJSONString(sysMenus), Duration.ofDays(7));
            }
        }
        // 空的就直接返回
        if (CollectionUtils.isEmpty(sysMenus)) {
            return Collections.emptyList();
        }
        // 组装树菜单
        return translateTree(sysMenus, 0L);
    }

    /**
     * 组装树的方法
     * @param sysMenus
     * @param pid
     * @return
     */
    private List<SysMenu> translateTree(List<SysMenu> sysMenus, long pid) {
        // 递归加载
        List<SysMenu> root = sysMenus.stream()
                .filter(sysMenu -> sysMenu.getParentId()
                        .equals(pid))
                .collect(Collectors.toList());
        root.forEach(r -> r.setList(translateTree(sysMenus, r.getMenuId())));

        return root;
    }
}
